home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / c2man-2.0pl33.lha / c2man-2.0 / symbol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-14  |  2.3 KB  |  120 lines

  1. /* $Id: symbol.c,v 2.0.1.2 1993/08/31 05:05:20 greyham Exp $
  2.  *
  3.  * Symbol table maintenance. Implements an abstract data type called
  4.  * the symbol table.
  5.  */
  6. #include "c2man.h"
  7. #include "symbol.h"
  8.  
  9. /* Create a symbol table.
  10.  * Return a pointer to the symbol table or NULL if an error occurs.
  11.  */
  12. SymbolTable *
  13. create_symbol_table ()
  14. {
  15.     SymbolTable *symtab;
  16.     int i;
  17.  
  18.     symtab = (SymbolTable *)safe_malloc(sizeof(SymbolTable));
  19.  
  20.     for (i = 0; i < SYM_MAX_HASH; ++i)
  21.     symtab->bucket[i] = NULL;
  22.  
  23.     return symtab;
  24. }
  25.  
  26.  
  27. /* Free the memory allocated to the symbol table.
  28.  */
  29. void
  30. destroy_symbol_table (symtab)
  31. SymbolTable *symtab;
  32. {
  33.     int i;
  34.     Symbol *sym, *next;
  35.  
  36.     for (i = 0; i < SYM_MAX_HASH; ++i) {
  37.     sym = symtab->bucket[i];
  38.     while (sym != NULL) {
  39.         next = sym->next;
  40.         free(sym->name);
  41.         free(sym);
  42.         sym = next;
  43.     }
  44.     }
  45.     free(symtab);
  46. }
  47.  
  48.  
  49. /* This is a simple hash function mapping a symbol name to a hash bucket. */
  50.  
  51. static unsigned int
  52. hash (name)
  53. char *name;
  54. {
  55.     char *s;
  56.     unsigned int h;
  57.  
  58.     h = 0;
  59.     s = name;
  60.     while (*s != '\0')
  61.     h = (h << 1) ^ *s++;
  62.     return h % SYM_MAX_HASH;
  63. }
  64.  
  65.  
  66. /* Search the list of symbols <list> for the symbol <name>.
  67.  * Return a pointer to the symbol or NULL if not found.
  68.  */
  69. static Symbol *
  70. search_symbol_list (list, name)
  71. Symbol *list;
  72. char *name;
  73. {
  74.     Symbol *sym;
  75.  
  76.     for (sym = list; sym != NULL; sym = sym->next) {
  77.     if (strcmp(sym->name, name) == 0)
  78.         return sym;
  79.     }
  80.     return NULL;
  81. }
  82.  
  83.  
  84. /* Look for symbol <name> in symbol table <symtab>.
  85.  * Return a pointer to the symbol or NULL if not found.
  86.  */
  87. Symbol *
  88. find_symbol (symtab, name)
  89. SymbolTable *symtab;
  90. char *name;
  91. {
  92.     return search_symbol_list(symtab->bucket[hash(name)], name);
  93. }
  94.  
  95.  
  96. /* If the symbol <name> does not already exist in symbol table <symtab>,
  97.  * then add the symbol to the symbol table.
  98.  * Return a pointer to the symbol or NULL on an error.
  99.  */
  100. Symbol *
  101. new_symbol (symtab, name, flags)
  102. SymbolTable *symtab;    /* symbol table */
  103. char *name;        /* symbol name */
  104. int flags;        /* symbol attributes */
  105. {
  106.     Symbol *sym;
  107.     int i;
  108.  
  109.     if ((sym = find_symbol(symtab, name)) == NULL) {
  110.     sym = (Symbol *)safe_malloc(sizeof(Symbol));
  111.     sym->name = strduplicate(name);
  112.     sym->flags = flags;
  113.     sym->valtype = SYMVAL_NONE;
  114.     i = hash(name);
  115.     sym->next = symtab->bucket[i];
  116.     symtab->bucket[i] = sym;
  117.     }
  118.     return sym;
  119. }
  120.